package com.kehongborui.fliggy.service.impl;

import com.alibaba.druid.support.json.JSONParser;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.util.JSONPObject;
import com.kehongborui.fliggy.entity.PassStation;
import com.kehongborui.fliggy.entity.Station;
import com.kehongborui.fliggy.entity.Vehicle;
import com.kehongborui.fliggy.exception.FliggyException;
import com.kehongborui.fliggy.mapper.PassStationMapper;
import com.kehongborui.fliggy.mapper.StationMapper;
import com.kehongborui.fliggy.mapper.VehicleMapper;
import com.kehongborui.fliggy.model.PassStationModel;
import com.kehongborui.fliggy.model.QueryVehicleModel;
import com.kehongborui.fliggy.model.VehicleModel;
import com.kehongborui.fliggy.service.VehicleService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import static com.kehongborui.fliggy.enums.ExceptionMessage.*;

/**
 * @author zhang peng yang ming
 * @CopyRight (C) http://www.csdn.com
 * @brief
 * @email 122162005@qq.com
 * @date 2018-08-21
 */
@Service
public class VehicleServiceImpl implements VehicleService {
    @Autowired
    private VehicleMapper vehicleMapper;

    @Autowired
    private PassStationMapper passStationMapper;

    @Autowired
    private StationMapper stationMapper;
    /**
     * 创建车辆信息
     *
     * @param vehicleModel
     * @return
     */
    @Transactional
    @Override
    public boolean create(VehicleModel vehicleModel) {
        // 1.根据列车编号查询列车信息是否已经存在（去重）
        Vehicle retVehicle = vehicleMapper.findByVehicleNo(vehicleModel.getVehicleNo());

        if (retVehicle != null) {
            throw new FliggyException(String.format(VEHICLE_INFO_IS_EXIST.getDesc(),
                    vehicleModel.getVehicleNo()));
        }
        // 2.保存列车信息，获取新建的列车的ID
        Vehicle vehicle = new Vehicle();
        BeanUtils.copyProperties(vehicleModel, vehicle);
        vehicle.setCreateTime(new Date());

        // 获取新建的列车的ID
        int ret = vehicleMapper.insertSelective(vehicle);

        // 3.根据保存列车返回的ID创建该列车对应的经停站
        List<PassStationModel> passStationModelList = vehicleModel.getPassStationModelList();
        List<PassStation> passStationList = new ArrayList<>();

        // 保存数据到PassStation中，方法1
        /**
         for (PassStationModel model : passStationModelList) {
         PassStation tmp = new PassStation();
         BeanUtils.copyProperties(model, tmp);
         tmp.setCreateTime(new Date());
         // 设置经停站所对应的列车id
         tmp.setVehicleId(vehicle.getId());

         passStationList.add(tmp);
         passStationMapper.insertSelective(tmp);
         }
         */
        // 校验seq 是否重复
        Set<Byte> seqs = passStationModelList.stream().map(model -> model.getSeq()).collect(Collectors.toSet());
        // 比较set中元素的个数与 passStationModelList中所有的seq的数量大小
        if (seqs.size() != passStationModelList.size()) {
            throw new FliggyException(String.format(PASS_STATION_SEQ_ERROR.getDesc(), vehicle.getVehicleNo()));
        }

        // 校验经停站是否重复
        Set<Long> stationIds = passStationModelList.stream().map(model -> model.getStationId()).collect(Collectors.toSet());
        // 比较set中元素的个数与 passStationModelList中所有的seq的数量大小
        if (stationIds.size() != passStationModelList.size()) {
            throw new FliggyException(String.format(PASS_STATION_ID_ERROR.getDesc(), vehicle.getVehicleNo()));
        }

        // 保存数据到PassStation中，方法2
        passStationList = passStationModelList.stream().map(model -> {

            PassStation passStation = new PassStation();
            BeanUtils.copyProperties(model, passStation);
            passStation.setCreateTime(new Date());
            // 检测经停站是否存
            // 设置经停站所对应的列车id
            passStation.setVehicleId(vehicle.getId());

            return passStation;
        }).collect(Collectors.toList());

        int r = passStationMapper.insertBatch(passStationList);
        return ret > 0 && r > 0;
    }

    /**
     * 更新车辆信息
     *
     * @param vehicleModel
     * @return
     */
    @Override
    public boolean update(VehicleModel vehicleModel) {
        // 首先判断id对否存在，如果不存在则抛出异常，反之则进行数据信息修改
        if (vehicleModel.getId() == null) {
            throw new FliggyException(String.format(VEHICLE_ID_IS_NOT_EXIST.getDesc(), vehicleModel.getVehicleNo()));
        }

        // 通过列车的名字查找列车信息
        Vehicle retVehicle = vehicleMapper.findByVehicleNo(vehicleModel.getVehicleNo());
        // 校验列车名是否重复
        if (retVehicle != null && retVehicle.getId().longValue() != vehicleModel.getId()) {
            throw new FliggyException(String.format(VEHICLE_INFO_IS_EXIST.getDesc(), vehicleModel.getVehicleNo()));
        }

        Vehicle vehicle = new Vehicle();
        BeanUtils.copyProperties(vehicleModel, vehicle);
        vehicle.setUpdateTime(new Date());
        int ret = vehicleMapper.updateByPrimaryKeySelective(vehicle);
        return ret > 0;
    }

    /**
     * 根据id 禁用列车
     *
     * @param id
     * @return
     */
    @Override
    public boolean delete(Long id) {
        // TODO
        return false;
    }

    /**
     * 根据列车编号与发车日期查询列车信息
     *
     * @param no      列车编号
     * @param depDate 发车日期
     * @return
     */
    @Override
    public VehicleModel findByNoAndDate(String no, Date depDate) {
        // TODO
        return null;
    }

    @Override
    public List<VehicleModel> findByDepArrStationAndDate(QueryVehicleModel queryVehicleModel) {
        // 查询起点站终点站对应的 ID
        List<Station> stationList = stationMapper.findByNames(queryVehicleModel);
        String depStationName = queryVehicleModel.getDepStation();
        String arrStationName = queryVehicleModel.getArrStation();
        // 根据起点站终点站的 ID 查询列车信息
        Map<String, String> query = new HashMap<>();

        for (Station s : stationList) {
//            Map<String, String> tmp = JSON.toJavaObject(JSON.parseObject(JSON.toJSONString(s)), Map.class);
            query.put(s.getName(), s.getId().toString());
        }
        queryVehicleModel.setArrStation(query.get(queryVehicleModel.getArrStation()));
        queryVehicleModel.setDepStation(query.get(queryVehicleModel.getDepStation()));

        List<Vehicle> vehicles = vehicleMapper.findByDepArrStationAndDate(queryVehicleModel);

        List<VehicleModel> modelList = vehicles.stream().map(vehicle -> {
            VehicleModel model = new VehicleModel();
            BeanUtils.copyProperties(vehicle, model);
            model.setDepStationName(depStationName);
            model.setArrStationName(arrStationName);
            return model;
        }).collect(Collectors.toList());

        return modelList;
    }

    @Override
    public Integer getSeatsAmount(String vehicleNo) {
        return vehicleMapper.getSeatsAmount(vehicleNo);
    }

    @Override
    public VehicleModel findById(long id) {
        Vehicle vehicle = vehicleMapper.selectByPrimaryKey(id);
        VehicleModel vehicleModel = new VehicleModel();
        BeanUtils.copyProperties(vehicle, vehicleModel);
        return vehicleModel;
    }
}
